<?php

namespace App\Admin\Controller;

class Authed extends Base {

    public function init() {

        parent::init();

        $uid = \Auth::getAuthedUid(MODULE_NAME);

        $role_ids = QF()->Admin()->getRoleIds($uid);

        $route_ids = QF()->Rbac()->Role()->getRouteIds($role_ids);

        $authed_routes = QF()->Rbac()->Route()->getAuthedTree($route_ids);

        if (!$authed_routes) {
            // 没有任何权限
            $this->gotoUrl('login', 'logout');
        }

        // 无需鉴权的路由表
        $ignore_urls = array(
            '^/admin/index/index$',
        );

        // 当前路由路径
        $this->request_path = $request_path = $this->request->requestPath();

        // 解析后的路由路径
        $parse_path = strtolower('/' . MODULE_NAME . '/' . str_replace('\\', '/', $this->request->getController()) . '/' . $this->request->getAction());

        // 匹配无需鉴权的路由
        $ignored = array_filter($ignore_urls, function ($ignore_url) use ($request_path, $parse_path) {
            return $this->_ignore_authed($ignore_url, $request_path, $parse_path);
        });

        // 当前url是否能通过鉴权
        $path_authed = false;
        $this->_path_authed($authed_routes, $request_path, $path_authed);

        // 当前路由不在无需鉴权的路由表里，且鉴权失败
        if (!$ignored && !$path_authed) {
            if ($this->request->isAjax()) {
                $this->fail('没有权限');
            } else {
                fail('没有权限');
            }
        }

        $this->authed_routes = $authed_routes;
    }

    /**
     * 判断当前访问路径是否在无需鉴权的路由表里
     * 
     * @param string $ignore_url
     * @param string $request_path
     * @param string $parse_path
     * @return bool
     */
    private function _ignore_authed($ignore_url, $request_path, $parse_path) {
        
        $ignore_url = '/' . str_replace('/', "\\/", $ignore_url) . '/';

        // 匹配请求路径
        $request_path_matched = preg_match($ignore_url, $request_path);
        if ($request_path_matched) {
            return true;
        }

        // 匹配解析后的路由路径
        $parse_path_matched = preg_match($ignore_url, $parse_path);
        if ($parse_path_matched) {
            return true;
        }

        // 没有匹配上
        return false;
    }
    
    /**
     * 判断当前访问路径是否能通过鉴权
     * 
     * @param \Treenode $authed_routes
     * @param string $request_path
     * @param bool $path_authed
     */
    private function _path_authed(&$authed_routes, &$request_path, &$path_authed) {
        foreach ($authed_routes as &$node) {

            if (strlen($node->getData('url')) && strpos($request_path, $node->getData('url')) === 0) {

                $path_authed = true;

                break;
            }

            if ($node->hasChild()) {
                $this->_path_authed($node->getChildNodes(), $request_path, $path_authed);
            }
        }
        unset($node);
    }

}
